package com.youlai.jdk;

import org.junit.jupiter.api.Test;

import java.util.*;

/**
 * java8实践小技巧
 *
 * @author zc
 * @date 2023-03-26 16:47
 */
public class Java8Practice {


    /**
     * 提前终止Lambda表达式中的forEach
     */
    @Test
    public void breakForEach() {
        List<String> list = Arrays.asList("hello", "world", "java", "8");
        System.out.println("==============只跳过本次循环=================");
        list.forEach(s -> {
            if (s.equals("java")) {
                return;
            }
            System.out.println(s);
        });
        System.out.println("==============使用异常跳出循环=================");
        try {
            list.forEach(s -> {
                if (s.equals("java")) {
                    throw new RuntimeException();
                }
                System.out.println(s);
            });
        } catch (Exception e) {
            System.out.println("捕获到异常");
        }

        System.out.println("==============改用for跳出循环=================");
        for (String s : list) {
            if (s.equals("java")) {
                return;
            }
            System.out.println(s);
        }
    }


    /**
     * 计算学生对象的总成绩
     */
    @Test
    public void sumScore() {
        List<StudentScore> studentScoreList = Arrays.asList(new StudentScore("张三", "语文", 70), new StudentScore("张三", "数学", 70), new StudentScore("张三", "英语", 65), new StudentScore("李四", "语文", 68), new StudentScore("李四", "数学", 70), new StudentScore("李四", "英语", 90), new StudentScore("王五", "语文", 80), new StudentScore("王五", "数学", 85), new StudentScore("王五", "英语", 70));

        Map<String, Integer> studentScoreMap = new HashMap<>();
        studentScoreList.forEach(studentScore -> {
            if (studentScoreMap.containsKey(studentScore.getStuName())) {
                studentScoreMap.put(studentScore.getStuName(), studentScoreMap.get(studentScore.getStuName()) + studentScore.getScore());
            } else {
                studentScoreMap.put(studentScore.getStuName(), studentScore.getScore());
            }
        });

        System.out.println(studentScoreMap);

        Map<String, Integer> studentScoreMap2 = new HashMap<>();


        studentScoreList.forEach(studentScore -> studentScoreMap2.merge(studentScore.getStuName(), studentScore.getScore(), (oldValue, newValue) -> oldValue + newValue));
        //merge() 方法会先判断指定的 key 是否存在，如果不存在，则添加键值对到 hashMap 中。
        System.out.println(studentScoreMap2);
    }

    /**
     * 1.使用Optional避免空指针异常
     * Optional是一个容器类，用来包含非空对象。
     */
    public void optional() {
        // 1.1 Optional.of()方法
        // Optional.of()方法会抛出空指针异常
        // Optional<String> optional = Optional.of(null);
        // System.out.println(optional.get());

        // 1.2 Optional.ofNullable()方法
        // Optional.ofNullable()方法不会抛出空指针异常
        Optional<String> optional = Optional.ofNullable(null);
        System.out.println(optional.orElse("null"));
    }

    /**
     * 2.使用Optional判断值是否存在
     * 使用Optional的isPresent()方法判断值是否存在
     */
    public void optionalIsPresent() {
        Optional<String> optional = Optional.ofNullable("hello");
        if (optional.isPresent()) {
            System.out.println(optional.get());
        }
    }

    /**
     * 3.使用Optional的map()方法
     * map()方法接收一个Function函数作为参数，该函数会被应用到Optional实例的值上，
     */
    public void optionalMap() {
        Optional<String> optional = Optional.ofNullable("hello");
        Optional<String> upperOptional = optional.map(String::toUpperCase);
        System.out.println(upperOptional.get());
    }

    /**
     * 4.使用Optional的flatMap()方法
     * 与map()方法类似，区别在于map()方法的参数是一个Function，而flatMap()方法的参数是一个Function，
     */
    public void optionalFlatMap() {
        Optional<String> optional = Optional.ofNullable("hello");
        Optional<String> upperOptional = optional.flatMap(s -> Optional.of(s.toUpperCase()));
        System.out.println(upperOptional.get());
    }

    /**
     * 5.使用Optional的filter()方法
     * filter()方法接收一个Predicate函数作为参数，该函数会被应用到Optional实例的值上，
     */
    public void optionalFilter() {
        Optional<String> optional = Optional.ofNullable("hello");
        Optional<String> upperOptional = optional.filter(s -> s.length() > 5);
        System.out.println(upperOptional.orElse("null"));
    }

    /**
     * 6.使用Optional的ifPresent()方法
     * ifPresent()方法接收一个Consumer函数作为参数，如果Optional实例有值存在，就会执行传入的Lambda表达式
     */
    public void optionalIfPresent() {
        Optional<String> optional = Optional.ofNullable("hello");
        optional.ifPresent(System.out::println);
    }

    /**
     * 7.使用Optional的orElse()方法
     * orElse()方法与orElseGet()方法类似，区别在于orElse()方法的参数是一个对象，而orElseGet()方法的参数是一个Supplier函数式接口
     */
    public void optionalOrElse() {
        Optional<String> optional = Optional.ofNullable(null);
        System.out.println(optional.orElse("null"));
    }

    /**
     * 8.使用Optional的orElseGet()方法
     * orElseGet()方法与orElse()方法类似，区别在于orElse()方法的参数是一个对象，而orElseGet()方法的参数是一个Supplier函数式接口
     */
    public void optionalOrElseGet() {
        Optional<String> optional = Optional.ofNullable(null);
    }
}
